package xyz.lwm.lazycat.beans;

import xyz.lwm.lazycat.annotation.Destroy;
import xyz.lwm.lazycat.annotation.Init;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * <h2>程序启动入口</h2>
 * <p>1. 快速启动</p>
 * <pre>{@code
 * public static void main(String[] args) {
 *     Application.run();
 * }
 * }</pre>
 *
 * <p>2. 自定义启动</p>
 * <pre>{@code
 * public static void main(String[] args) {
 *     Application app = new Application();
 *     app.addRegistry(new BeanDesignRegistryCustomizer() {});
 *     app.addBeanRefFilter(new BeanRefFilterCustomizer());
 *     app.addBeanRenamer(new MyBeanRenamer());
 *     app.start();
 *     Beans beans = app.getBeans();
 *     TestService testService = beans.getBean(TestService.class);
 * }
 * }</pre>
 *
 * @author lwm
 */
public class Application {

    private final BeanContextStarter beanContextStarter = new BeanContextStarter();

    /**
     * 添加 BeanDesignRegistryCustomizer, 用于扩展注册 design 到 BeanDesignRegistry
     *
     * @param registryCustomizer BeanDesignRegistryCustomizer
     */
    public void addRegistry(BeanDesignRegistryCustomizer registryCustomizer) {
        beanContextStarter.addBeanDesignRegistryCustomizer(registryCustomizer);
    }

    /**
     * 添加 BeanRefFilter, 用于过滤 BeanRef, test 模块中用的较多
     *
     * @param beanRefFilter BeanRefFilter
     */
    public void addBeanRefFilter(BeanRefFilter beanRefFilter) {
        beanContextStarter.addBeanRefFilter(beanRefFilter);
    }

    /**
     * 添加 BeanRenamer, 用于重命名 Bean
     *
     * @param renamer BeanRenamer
     */
    public void addBeanRenamer(BeanRenamer renamer) {
        beanContextStarter.addBeanRenamer(renamer);
    }

    /**
     * 获取 Beans
     *
     * @return Beans
     */
    public Beans getBeans() {
        return beanContextStarter.getBeans();
    }

    /**
     * 启动程序
     */
    public void start() {
        beanContextStarter.start();
    }

    /**
     * 运行程序
     */
    public static void run() {
        new Application().start();
    }

    /**
     * 说明
     */
    public static void introduce() {
        System.out.println("============== Program Extensions ==============");
        System.out.println("bean design customize: " + BeanDesignRegistryCustomizer.class.getName());
        System.out.println("bean customize: " + BeansCustomizer.class.getName());
        System.out.println("setting customize: " + SettingCustomizer.class.getName());
        System.out.println("bean design import registrar: " + BeanDesignImportRegistrar.class.getName());
        System.out.println();

        System.out.println("============== Bean Life ==============");
        System.out.println("bean life cycle: " + BeanLifecycle.class.getName());
        System.out.println("post construct: " + PostConstruct.class.getName());
        System.out.println("init :" + Init.class.getName());
        System.out.println("pre destroy: " + PreDestroy.class.getName());
        System.out.println("destroy: " + Destroy.class.getName());
        System.out.println("bean post processor: " + BeanPostProcessor.class.getName());
        System.out.println("app runner: " + AppRunner.class.getName());
        System.out.println();

        System.out.println("============== Util ==============");
        System.out.println("bean design builder: " + BeanDesignBuilder.class.getName());
        System.out.println("bean design util: " + BeanDesignUtil.class.getName());
    }

}
